<?php
// +----------------------------------------------------------------------
// | RXThinkCMF敏捷开发框架 [ 赋能开发者，助力企业发展 ]
// +----------------------------------------------------------------------
// | 版权所有 2018~2023 南京RXThinkCMF研发中心
// +----------------------------------------------------------------------
// | Licensed LGPL-3.0 RXThinkCMF并不是自由软件，未经许可禁止去掉相关版权
// +----------------------------------------------------------------------
// | 官方网站: https://www.rxthink.cn
// +----------------------------------------------------------------------
// | Author: @牧羊人 团队荣誉出品
// +----------------------------------------------------------------------
// | 版权和免责声明:
// | 本团队对该软件框架产品拥有知识产权（包括但不限于商标权、专利权、著作权、商业秘密等）
// | 均受到相关法律法规的保护，任何个人、组织和单位不得在未经本团队书面授权的情况下对所授权
// | 软件框架产品本身申请相关的知识产权，禁止用于任何违法、侵害他人合法权益等恶意的行为，禁
// | 止用于任何违反我国法律法规的一切项目研发，任何个人、组织和单位用于项目研发而产生的任何
// | 意外、疏忽、合约毁坏、诽谤、版权或知识产权侵犯及其造成的损失 (包括但不限于直接、间接、
// | 附带或衍生的损失等)，本团队不承担任何法律责任，本软件框架禁止任何单位和个人、组织用于
// | 任何违法、侵害他人合法利益等恶意的行为，如有发现违规、违法的犯罪行为，本团队将无条件配
// | 合公安机关调查取证同时保留一切以法律手段起诉的权利，本软件框架只能用于公司和个人内部的
// | 法律所允许的合法合规的软件产品研发，详细声明内容请阅读《框架免责声明》附件；
// +----------------------------------------------------------------------

namespace app\admin\service;

use app\admin\model\Classes;
use app\admin\model\Schoole;
use app\admin\model\Teacher;
use app\admin\model\User;
use app\admin\model\UserRole;
use think\Db;

/**
 * 老师管理-服务类
 * @author 牧羊人
 * @since: 2024/06/25
 * Class TeacherService
 * @package app\admin\service
 */
class TeacherService extends BaseService
{

    // 用户ID
    protected $userId = 0;
    public static $staticUserId = 0;

    // 前端SEX值转换成后端GENDER值
    const SEX_GENDER = [
        0 => 2,
        1 => 1,
        2 => 3
    ];
    /**
     * 删除记录
     * @return array
     * @since 2020/11/12
     * @author 牧羊人
     */
    public function delete()
    {
        return $this->remove(function ($info) {
            $ids = array_column($info, 'id');
            $exists = (new Classes)
                ->distinct(true)
                ->where(function ($query) use ($ids) {
                    foreach ($ids as $id) {
                        $query->whereOr('find_in_set(' . $id. ',teacher_ids)');
                    }
                })
                ->where('mark', 1)
                ->column('id');
            if ($exists) {
                throw new \Exception( '有老师关联班级');
            }
        });
    }
    /**
     * 构造函数
     * LevelService constructor.
     */
    public function __construct()
    {
        $this->model = new Teacher();

        // 解析Token获取用户ID
        $token = request()->header("Authorization");
        $token = str_replace("Bearer ", null, $token);
        $jwt = new \Jwt();
        $this->userId = $jwt->verifyToken($token);
    }

    /**
     * 获取数据列表
     * @return array
     * @since 2024/06/25
     * @author 牧羊人
     */
    public function getList($page = 0, $limit = 0)
    {
        $param = request()->param();

        // 获取参数值
        $schoole_id = getter($param, "schoole_id", 0);
        $sex = getter($param, "sex", '');
        $keyword = getter($param, "keyword", '');

        // 查询条件
        $map = [];

        if ($schoole_id) $map[] = ['schoole_id', '=', $schoole_id];
        if ($sex !== '') $map[] = ['sex', '=', $sex];
        if ($keyword) $map[] = ['realname|username|mobile', 'like', '%' . $keyword . '%'];

        $map[] = ['mark', '=', 1];  //有效标识 = 1

        $sort = 'id desc';

        $page = $page ?: request()->param('page', 1);
        $limit = $limit ?: request()->param('limit', 20);

        $teacher = getTeacher($this->userId);
        if ($teacher) {
            $map[] = ['id', '=', $teacher['id']];
        }


        $query = $this->model->with(['role', 'schoole'])->where($map);
        $count = $query->count();
        $list = $query->order($sort)->page($page, $limit)->select();

        $res = [
            "msg" => '获取成功',
            "code" => 0,
            "count" => $count,
            "data" => $list,
        ];

        return $res;
    }

    /**
     * 添加或编辑
     * @return mixed
     * @since 2020/11/20
     * @author 牧羊人
     */
    public function edit()
    {
        // 请求参数
        $data = request()->param();

        $username = trim(getter($data, 'username', ''));    //账号名
        $password = trim(getter($data, 'password', ''));    //密码
        $id = trim(getter($data, "id", 0));   //用户ID

        // 查询条件
        $map = [];
        $map[] = ['username', '=', $username];
        if ($id) $map[] = ['id', '<>', $id];
        $map[] = ['mark', '=', 1];  //有效标识 = 1

        // 用户名重复性验证
        $count = $this->model->where($map)->count();
        if (empty($id) && $count > 0) {
            return message("系统中已存在相同的用户名", false);
        }

        // 添加时设置密码
        if (!$id) {
            $data['password'] = get_password($password . $username);
        } else {
            // 获取用户信息
            $info = $this->model->getInfo($id);
            if (!$info) return message("该老师信息不存在", false);

            $data['password'] = $password ? get_password($password . $username) : $info['password'];
        }

        // 头像处理
        $avatar = getter($data, 'avatar', '');
        if(isset($data['avatar'])){
            if ($avatar) {
            } $data['avatar'] = strpos($avatar, "temp") ? save_image($avatar, 'teacher') : str_replace(IMG_URL, "", $data['avatar']);
            if(strpos($data['avatar'],':image') !== false){
                $data['avatar'] = '';
            }
        }

        // 判断think_user 表中的学生老师账号是否存在，存在更新，不存在增加
        $map[] = ['user_type', '=', 1];  //用户类型 1=学校老师,2=学生家长

        $userModel = new User();
        $userRole = new UserRole();
        $user = $userModel->getOne($map);
        if ($user) {
            $user_update_data['id'] = $user['id'];
            if (isset($data['realname']) && $data['realname']) $user_update_data['realname'] = $data['realname'];
            if (isset($data['sex']) && $data['sex'] !== '') $user_update_data['gender'] = self::SEX_GENDER[$data['sex']];
            if (isset($data['avatar']) && $data['avatar']) $user_update_data['avatar'] = $data['avatar'];
            if (isset($data['mobile']) && $data['mobile']) $user_update_data['mobile'] = $data['mobile'];
            if (isset($data['schoole_id']) && $data['schoole_id']) $user_update_data['schoole_id'] = $data['schoole_id'];
            if (isset($data['password']) && $data['password']) $user_update_data['password'] = $data['password'];
            if(!empty($data['schoole_id'])){
                $schoole = Db::table('think_schoole')->where('id',$data['schoole_id'])->where('mark',1)->find();
               if($schoole){
                   $user_update_data['province_code'] = $schoole['province_code'];
                   $user_update_data['city_code'] = $schoole['city_code'];
                   $user_update_data['district_code'] = $schoole['district_code'];
                   $user_update_data['streets_code'] = $schoole['streets_code'];
               }
            }
            $userModel->edit($user_update_data);
            $userRole->doUpdate(['role_id' => 10], ['user_id' => $user['id']]);
        } else {
            $schoole = Db::table('think_schoole')->where('id',$data['schoole_id'])->where('mark',1)->find();
            $userId = $userModel->edit([
                'user_type' => 1,
                'realname' => isset($data['realname']) && $data['realname'] ? $data['realname'] : '',
                'username' => isset($data['username']) && $data['username'] ? $data['username'] : '',
                'gender' => isset($data['sex']) && $data['sex'] !== '' ? self::SEX_GENDER[$data['sex']] : 3,
                'avatar' => isset($data['avatar']) && $data['avatar'] ? $data['avatar'] : '',
                'mobile' => isset($data['mobile']) && $data['mobile'] ? $data['mobile'] : '',
                'schoole_id' => isset($data['schoole_id']) && $data['schoole_id'] ? $data['schoole_id'] : 0,
                'province_code' => $schoole? $schoole['province_code'] : '',
                'city_code' => $schoole? $schoole['city_code'] : '',
                'district_code' => $schoole? $schoole['district_code'] : '',
                'streets_code' => $schoole? $schoole['streets_code'] : '',
                'password' => $data['password']
            ]);
            $userRole->doInsert(['user_id' => $userId, 'role_id' => 10]);
        }

        return parent::edit($data); // TODO: Change the autogenerated stub
    }

    /**
     * 导入Excel
     */
    public function importExcel()
    {
        //学校ID
        $schoole_id = request()->param('schoole_id', '');
        if (!$schoole_id) return message("缺少学校ID(schoole_id)参数值", false);

        $schoole = app()->make(Schoole::class)->get($schoole_id);
        if (!$schoole) return message("该学校不存在", false);

        // 检查文件扩展名
        $file = $_FILES['file'];
        if (!$file) return message("请上传文件", false);

        $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
        if (strtolower($extension) !== 'xlsx') return message("上传的文件必须是 .xlsx 格式。", false);

        $error = "";
        // 上传文件(非图片)
        $result = upload_file('file', 'import/', $error);
        if (!$result) return message($error, false);

        // 文件路径
        $filePath = FILE_PATH . $result;
        if (!file_exists($filePath)) return message("文件不存在", false);

        // 读取文件
        $objPHPExcel = \PHPExcel_IOFactory::load($filePath); //获取sheet表格数目
        $sheetSelected = 0;
        $objPHPExcel->setActiveSheetIndex($sheetSelected); //获取表格行数
        $activeSheet = $objPHPExcel->getActiveSheet();
        $rowCount = $activeSheet->getHighestRow(); //获取表格列数
        $columnCount = $activeSheet->getHighestColumn();
        $totalNum = $rowCount - 1;

        //验证文件内容
        if ($totalNum < 1) return message("请填写数据后上传", false);
        if ($columnCount !== 'E') return message("请不要更改模板文件格式，填写数据后上传", false);

        $dataArr = array();
        $sex_arr = ['女', '男', '保密'];
        $create_user = $this->userId;
        $create_time = time();

        // 循环读取行数据
        for ($row = 2; $row <= $rowCount; $row++) {
            // 获取列值
            $username = trim($activeSheet->getCell("A" . $row)->getValue());
            if (!$username) return message(sprintf('第%s行，账号名称未填写', $row), false);
            $map3 = [];
            $map3[] = ['mark', '=', 1];  //有效标识 = 1
            // 查询条件
            $map3[] = ['username', '=', $username];
            // 用户名重复性验证
            $count = $this->model->where($map3)->count();
            if ($count > 0) {
                return message("系统中已存在相同的用户名", false);
            }
            $password = trim($activeSheet->getCell("B" . $row)->getValue());
            if ($password) $password = get_password($password . $username);

            $realname = trim($activeSheet->getCell("C" . $row)->getValue());
            $mobile = trim($activeSheet->getCell("D" . $row)->getValue());
            if (!is_mobile($mobile)) return message(sprintf('第%s行，联系电话：%s 不正确', $row, $mobile), false);

            $sex = trim($activeSheet->getCell("E" . $row)->getValue());
            if ($sex) $sex = array_search($sex, $sex_arr);

            $dataArr[] = compact('username', 'password', 'realname', 'mobile', 'sex', 'schoole_id', 'create_user', 'create_time');
        }

        Db::startTrans();
        try {
            $this->model->saveAll($dataArr);
            Db::commit();
        } catch (\Throwable $e) {
            Db::rollback();
            trace('导入老师异常：' . $e->getTraceAsString(), 'error');
            return message($e->getMessage(), false);
        }

        return message("本次成功导入{$totalNum}条数据");
    }

    /**
     * 导出Excel
     * @throws \PHPExcel_Exception
     * @throws \PHPExcel_Reader_Exception
     * @throws \PHPExcel_Writer_Exception
     */
    public function exportExcel()
    {
        set_time_limit(0);
        $export_type = request()->param('export_type', 0);
        $schoole_id = request()->param('schoole_id', '');
        $schoole_name = '';

        // 获取导出的数据源
        $res = $this->getList(1, 20000);
        $list = $res['data'];

        // 实例化PHPExcel类
        $objPHPExcel = new \PHPExcel();
        // 激活当前的sheet表
        $activeSheet = $objPHPExcel->setActiveSheetIndex(0);
        //5.设置表格头（即excel表格的第一行）
        $activeSheet->setCellValue('A1', '姓名')
            ->setCellValue('B1', '账号名称')
            ->setCellValue('C1', '角色')
            ->setCellValue('D1', '联系方式')
            ->setCellValue('E1', '所属学校')
            ->setCellValue('F1', '性别')
            ->setCellValue('G1', '创建时间');

        // 设置单元格宽度
        $activeSheet->getColumnDimension('A')->setWidth(20);
        $activeSheet->getColumnDimension('B')->setWidth(20);
        $activeSheet->getColumnDimension('C')->setWidth(20);
        $activeSheet->getColumnDimension('D')->setWidth(20);
        $activeSheet->getColumnDimension('E')->setWidth(80);
        $activeSheet->getColumnDimension('F')->setWidth(20);
        $activeSheet->getColumnDimension('G')->setWidth(20);


        // 循环刚取出来的数组，将数据逐一添加到excel表格
        $sex_arr = ['女', '男', '保密'];
        for ($i = 0; $i < count($list); $i++) {
            $activeSheet->setCellValue('A' . ($i + 2), $list[$i]['realname']);
            $activeSheet->setCellValue('B' . ($i + 2), $list[$i]['username']);
            $activeSheet->setCellValue('C' . ($i + 2), $list[$i]['role_name']);
            $activeSheet->setCellValue('D' . ($i + 2), $list[$i]['mobile']);
            $activeSheet->setCellValue('E' . ($i + 2), $list[$i]['schoole_name']);
            $activeSheet->setCellValue('F' . ($i + 2), $sex_arr[$list[$i]['sex']]);
            $activeSheet->setCellValue('G' . ($i + 2), date('Y-m-d H:i:s', $list[$i]['create_time']));
            $schoole_name = $list[$i]['schoole_name'];
        }
        // 设置保存的Excel表格名称
        $filename = $schoole_name . '_老师导出_' . date('YmdHis', time()) . ".xlsx";
        // 设置当前激活的sheet表格名称
        $activeSheet->setTitle('Sheet1');

        if ($export_type) { //直接浏览器输出
            header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
            header('Content-Disposition: attachment;filename="' . $filename);
            header('Cache-Control: max-age=0');
            // If you're serving to IE 9, then the following may be needed
            header('Cache-Control: max-age=1');
            // If you're serving to IE over SSL, then the following may be needed
            header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
            header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
            header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
            header('Pragma: public'); // HTTP/1.0
            $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
            $objWriter->save('php://output');
            return;
        }

        // 保存本地文件
        $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
        $file_dir = UPLOAD_TEMP_PATH . "/" . $schoole_id . "/";
        $savePath = $file_dir . $filename;

        // 检测文件路径是否存在,不存在则创建
        if (!file_exists($file_dir)) {
            mkdirs($file_dir, 0777, true);
        }
        $objWriter->save($savePath);

        // 文件地址
        $filePath = get_image_url(str_replace(PUBLIC_PATH, "", $savePath));
        return message("操作成功", true, $filePath);
    }
}
